﻿//+-------------------------------------------------------------------------------------------------------------------------------------------------------
//
//Description: MainWindow
//Author: Aravind Ramarathinam (aravr@microsoft.com)
//
//Copyright © Microsoft Corporation
//Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. 
//You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 
//
//THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, 
//INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT. 
//See the Apache Version 2.0 License for specific language governing permissions and limitations under the License.
// 
//--------------------------------------------------------------------------------------------------------------------------------------------------------



using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.Serialization.Json;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Forms;
using System.Windows.Input;
using System.Windows.Media.Imaging;
using VmroleAuthor.Helpers;
using VmroleAuthor.Models;
using VmroleAuthor.ViewModels;
using Application = System.Windows.Application;
using DataFormats = System.Windows.DataFormats;
using DragEventArgs = System.Windows.DragEventArgs;
using MessageBox = System.Windows.Forms.MessageBox;

namespace VmroleAuthor.Views
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow
    {
        private readonly DefinitionViewModel definitionViewModel;

        public MainWindow()
        {
            InitializeComponent();
            definitionViewModel = new DefinitionViewModel();
            this.DataContext = definitionViewModel;
        }


        public DefinitionViewModel DefinitionViewModel
        {
            get { return this.definitionViewModel; }
        }

        private void DefinitionTree_OnSelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
        {
            //var obj = e.NewValue;
            //MessageBox.Show("Selected Item in Tree of type: " + obj.GetType().ToString());
        }

        private void Open_File_Click(object sender, RoutedEventArgs e)
        {
            var ofw = new OpenFileWindow();
            Window window = new Window
            {
                Title = "Open Resource Extension or Definition Package",
                Icon = new BitmapImage(new Uri("pack://application:,,,/VmroleAuthor;component/Img/Tool.png")),
                Content = ofw,
                Name = OpenFileWindow.OpenFileWindowName,
                SizeToContent = SizeToContent.Height,
                Width = 700
            };
            window.ShowDialog();
            if (ofw.DataValid)
            {
                if (ofw.CloudServiceManagerFileType == CloudServiceManagerFileType.ResourceExtensionPackage)
                {
                    this.OpenResourceExtension(ofw.ResourceExtensionStorageInfo);
                }
                else if ((ofw.CloudServiceManagerFileType == CloudServiceManagerFileType.ResourceDefinitionPackage) ||
                    (ofw.CloudServiceManagerFileType == CloudServiceManagerFileType.ResourceDefinition))
                {
                    this.OpenResourceDefinition(ofw.ResourceDefinitionStorageInfo);
                }

            }
        }

        public void OpenResourceExtension(ResourceExtensionStorageInfo resourceExtensionStorageInfo)
        {
            try
            {
                this.definitionViewModel.OpenAndAddNewResourceExtensionToTheView(resourceExtensionStorageInfo);
            }
            catch (Exception ex)
            {
                string jsMsg = ex.Message;
                string exMsg = ex.ToString();
                string dsMsg = string.Empty;
                string dxMsg = string.Empty;
                try
                {
                    //TO get more detailed exception
                    using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(resourceExtensionStorageInfo.JsonFileName)))
                    {
                        DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(VMRoleResourceExtensionDefinition));
                        VMRoleResourceExtensionDefinition deserializedObject = (VMRoleResourceExtensionDefinition)ser.ReadObject(ms);
                    }
                }
                catch (Exception iex)
                {
                    dsMsg = iex.Message;
                    dxMsg = iex.ToString();
                }
                MessageBox.Show(
                    string.Format(
                        "Exception while opening resource extension. Deserializing json {0} in package {1}. Exception details : " +
                        " JavaScriptSerializer: {2} {3} \n DataContractSerializer: {4} {5}", resourceExtensionStorageInfo.JsonFileName, resourceExtensionStorageInfo.FileToSavePath,
                         jsMsg, exMsg, dsMsg, dxMsg), DefinitionViewModel.ToolHeader);
            }
        }

        public void OpenResourceDefinition(ResourceDefinitionStorageInfo resourceDefinitionStorageInfo)
        {
            try
            {
                this.definitionViewModel.OpenAndAddNewResourceDefinitionToTheView(resourceDefinitionStorageInfo);
            }
            catch (Exception ex)
            {
                MessageBox.Show(string.Format("Exception while opening resource definition. Package {0}. Exception details : {1}", resourceDefinitionStorageInfo.FileToSavePath, ex.Message), DefinitionViewModel.ToolHeader);
            }

        }

        private void File_New_WindowsResourceExtension_Click(object sender, RoutedEventArgs e)
        {
            var nfw = new NewFileWindow();
            nfw.WindowTitle = "New Windows Resource Extension";
            nfw.CloudServiceManagerFileType = CloudServiceManagerFileType.ResourceExtensionPackage;
            Window window = new Window
            {
                Title = nfw.WindowTitle,
                Icon = new BitmapImage(new Uri("pack://application:,,,/VmroleAuthor;component/Img/Tool.png")),
                Content = nfw,
                Name = NewFileWindow.NewFileWindowName,
                SizeToContent = SizeToContent.Height,
                Width = 700
            };
            window.ShowDialog();
            if (nfw.DataValid)
            {
                ResourceExtensionStorageInfo resourceExtensionStorageInfo = new ResourceExtensionStorageInfo
                    {
                        FileToSavePath = nfw.FileToSavePath,
                        JsonFileName = nfw.JsonFileNameInsidePackage,
                        WorkingDir = nfw.WorkingDir.Text
                    };
                this.definitionViewModel.CreateAndAddNewResourceExtensionToTheView(resourceExtensionStorageInfo, true);
            }
        }

        private void File_New_LinuxResourceExtension_Click(object sender, RoutedEventArgs e)
        {
            var nfw = new NewFileWindow();
            nfw.WindowTitle = "New Linux Resource Extension";
            nfw.CloudServiceManagerFileType = CloudServiceManagerFileType.ResourceExtensionPackage;
            Window window = new Window
            {
                Title = nfw.WindowTitle,
                Icon = new BitmapImage(new Uri("pack://application:,,,/VmroleAuthor;component/Img/Tool.png")),
                Content = nfw,
                Name = NewFileWindow.NewFileWindowName,
                SizeToContent = SizeToContent.Height,
                Width = 700
            };
            window.ShowDialog();
            if (nfw.DataValid)
            {
                ResourceExtensionStorageInfo resourceExtensionStorageInfo = new ResourceExtensionStorageInfo
                {
                    FileToSavePath = nfw.FileToSavePath,
                    JsonFileName = nfw.JsonFileNameInsidePackage,
                    WorkingDir = nfw.WorkingDir.Text
                };
                this.definitionViewModel.CreateAndAddNewResourceExtensionToTheView(resourceExtensionStorageInfo, false);
            }
        }

        private void HandleValidationResultsDoubleClick(object sender, MouseButtonEventArgs e)
        {
            var validationResult = ((ListBoxItem)sender).Content as CloudServiceModelValidationResult; //Casting back to the binded Track
            if (validationResult != null && validationResult.TreeViewItemViewModel != null)
            {
                validationResult.TreeViewItemViewModel.IsSelected = true;
            }
        }

        private void File_New_Resource_Definition_Package_Click(object sender, RoutedEventArgs e)
        {
            var nfw = new NewFileWindow();
            nfw.WindowTitle = "New Resource Definition Package";
            nfw.CloudServiceManagerFileType = CloudServiceManagerFileType.ResourceDefinitionPackage;
            Window window = new Window
            {
                Title = nfw.WindowTitle,
                Icon = new BitmapImage(new Uri("pack://application:,,,/VmroleAuthor;component/Img/Tool.png")),
                Content = nfw,
                Name = NewFileWindow.NewFileWindowName,
                SizeToContent = SizeToContent.Height,
                Width = 700
            };
            window.ShowDialog();
            if (nfw.DataValid)
            {
                ResourceDefinitionStorageInfo storageInfo = new ResourceDefinitionStorageInfo
                {
                    FileToSavePath = nfw.FileToSavePath,
                    JsonFileName = nfw.JsonFileNameInsidePackage,
                    WorkingDir = nfw.WorkingDir.Text,
                    ViewDefFileName = nfw.ViewDefFileName,
                    IsResdefPkg = true
                };
                this.definitionViewModel.CreateAndAddNewResourceDefinitionToTheView(storageInfo);
            }
        }

        private void File_New_Resource_Definition_File_Click(object sender, RoutedEventArgs e)
        {
            var nfw = new NewFileWindow();
            nfw.WindowTitle = "New Resource Definition File";
            nfw.CloudServiceManagerFileType = CloudServiceManagerFileType.ResourceDefinition;
            Window window = new Window
            {
                Title = nfw.WindowTitle,
                Icon = new BitmapImage(new Uri("pack://application:,,,/VmroleAuthor;component/Img/Tool.png")),
                Content = nfw,
                Name = NewFileWindow.NewFileWindowName,
                SizeToContent = SizeToContent.Height,
                Width = 700
            };
            window.ShowDialog();
            if (nfw.DataValid)
            {
                ResourceDefinitionStorageInfo storageInfo = new ResourceDefinitionStorageInfo
                {
                    FileToSavePath = nfw.FileToSavePath,
                    JsonFileName = nfw.FileToSavePath,
                    WorkingDir = nfw.WorkingDir.Text
                };
                this.definitionViewModel.CreateAndAddNewResourceDefinitionToTheView(storageInfo);
            }
        }

        private void HelpButton_OnClick(object sender, RoutedEventArgs e)
        {
            var fb = new AboutFeedback();
            Window window = new Window
            {
                Title = "About VM Role Authoring Tool",
                Icon = new BitmapImage(new Uri("pack://application:,,,/VmroleAuthor;component/Img/Tool.png")),
                Content = fb,
                Name = NewFileWindow.NewFileWindowName,
                SizeToContent = SizeToContent.WidthAndHeight
            };
            window.ShowDialog();
        }

        private void MainWindow_OnDrop(object sender, DragEventArgs e)
        {
            string[] droppedFilenames = e.Data.GetData(DataFormats.FileDrop, true) as string[];
            if (droppedFilenames != null)
            {
                foreach (string droppedFilename in droppedFilenames)
                {
                    string workingDir = OpenFileWindow.GetWorkingDirectoryName(droppedFilename);
                    var cloudServiceManagerFileType = PackagingFormatHelper.GetFileType(droppedFilename);
                    if (PackagingFormatHelper.IsPackage(droppedFilename))
                    {
                        PackagingFormatHelper.ExtractPackage(droppedFilename, workingDir, cloudServiceManagerFileType);
                        if (cloudServiceManagerFileType == CloudServiceManagerFileType.ResourceExtensionPackage)
                        {
                            string jsonFileNameInsidePackage;
                            PackagingFormatHelper.GetResextPkgDetails(workingDir, out jsonFileNameInsidePackage);
                            var resourceExtensionStorageInfo = new ResourceExtensionStorageInfo
                            {
                                FileToSavePath = droppedFilename,
                                JsonFileName = jsonFileNameInsidePackage,
                                WorkingDir = workingDir
                            };
                            this.OpenResourceExtension(resourceExtensionStorageInfo);
                        }
                        else if (cloudServiceManagerFileType == CloudServiceManagerFileType.ResourceDefinitionPackage)
                        {
                            string resdefJsonFile;
                            string viewdefJsonFile;
                            string smallIconFile, mediumIconFile, largeIconFile;
                            List<string> resourceFileNames;
                            PackagingFormatHelper.GetResdefPkgDetails(workingDir, out resdefJsonFile, out viewdefJsonFile, out smallIconFile, out mediumIconFile, out largeIconFile, out resourceFileNames);
                            var resourceDefinitionStorageInfo = new ResourceDefinitionStorageInfo
                            {
                                FileToSavePath = droppedFilename,
                                JsonFileName = resdefJsonFile,
                                ViewDefFileName = viewdefJsonFile,
                                SmallIconFileName = smallIconFile,
                                MediumIconFileName = mediumIconFile,
                                LargeIconFileName = largeIconFile,
                                ResourceFileNames = resourceFileNames,
                                WorkingDir = workingDir,
                                IsResdefPkg = true
                            };
                            this.OpenResourceDefinition(resourceDefinitionStorageInfo);
                        }
                    }
                    else
                    {
                        if (cloudServiceManagerFileType == CloudServiceManagerFileType.ResourceDefinition)
                        {
                            var resourceDefinitionStorageInfo = new ResourceDefinitionStorageInfo
                            {
                                FileToSavePath = droppedFilename,
                                JsonFileName = droppedFilename,
                                WorkingDir = workingDir,
                                IsResdefPkg = false
                            };
                            this.OpenResourceDefinition(resourceDefinitionStorageInfo);
                        }
                    }
                }
            }
        }

        private void MenuItem_OnExitClick(object sender, RoutedEventArgs e)
        {
            if (MessageBox.Show("Save all open packages?", DefinitionViewModel.ToolHeader, MessageBoxButtons.YesNo, MessageBoxIcon.Question) == System.Windows.Forms.DialogResult.Yes)
            {
                this.definitionViewModel.SaveAll();
            }
            Application.Current.Shutdown();
        }
    }
}
